package com.semeureka.frame.mina;

import java.io.IOException;
import java.util.Map;

import javax.annotation.PreDestroy;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoService;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;

public class MinaService {
	private static final Logger LOGGER = LoggerFactory.getLogger(MinaService.class);
	private Map<IoService, Boolean> services;

	public void setServices(Map<IoService, Boolean> services) {
		this.services = services;
	}

	public void start(IoService service) throws IOException {
		services.put(service, true);
		start0(service);
	}

	private void start0(IoService service) throws IOException {
		if (service instanceof IoAcceptor) {
			IoAcceptor acceptor = (IoAcceptor) service;
			acceptor.bind();
			LOGGER.info("监听：{}，启动成功", acceptor.getDefaultLocalAddress());
		} else if (service instanceof IoConnector) {
			IoConnector connector = (IoConnector) service;
			ConnectFuture connectFuture = connector.connect().awaitUninterruptibly();
			if (connectFuture.isConnected()) {
				LOGGER.info("连接：{}，启动成功", connector.getDefaultRemoteAddress());
			} else {
				throw new RuntimeException("连接超时");
			}
		}
	}

	public void stop(IoService service) {
		services.put(service, false);
		stop0(service);
	}

	private void stop0(IoService service) {
		if (service instanceof IoAcceptor) {
			IoAcceptor acceptor = (IoAcceptor) service;
			acceptor.unbind();
			LOGGER.info("监听：{}，关闭成功", acceptor.getDefaultLocalAddress());
		} else if (service instanceof IoConnector) {
			IoConnector connector = (IoConnector) service;
			for (IoSession session : connector.getManagedSessions().values()) {
				session.close(true);
			}
			LOGGER.info("连接：{}，关闭成功", connector.getDefaultRemoteAddress());
		}
	}

	@Scheduled(fixedDelay = 120000)
	public void check() {
		for (IoService service : services.keySet()) {
			try {
				if (Boolean.TRUE.equals(services.get(service)) && !service.isActive()) {
					start0(service);
				} else if (Boolean.FALSE.equals(services.get(service)) && service.isActive()) {
					stop0(service);
				}
			} catch (Exception e) {
				LOGGER.error("启动监听/连接出错：" + e.getMessage(), e);
			}
		}
	}

	@PreDestroy
	public void destroy() {
		for (IoService service : services.keySet()) {
			if (!service.isDisposing()) {
				service.dispose();
			}
		}
	}
}
